/*
 * port_aos.c -  AOS 平台硬件抽象层实现
 *
 * Author: xiaobo@YGL (xiaobocwb@gmail.com)
 * Version: 1.0.0
 * Date: 2025-01-14
 */


#include "port_aos.h"

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "xp_lpuart.h"
#include <aos/kernel.h>

/*******************************************************************************
 * 硬件抽象层
 *******************************************************************************/
static int uart_send(void *dev, uint8_t *data, uint16_t len) {
    if (!data || len == 0) {
        return -1;
    }
    uint8_t port = *(uint8_t*)dev;
    bool ret = push_to_tx_ringbuffer(port, data, len);  
    if (!ret) {
        return -1;
    }
    flush_tx_ringbuffer(port);  // 这里尝试flush一次,如果当前DMA忙失败,会在接收任务中轮询flush
    return len;
}

static void* hal_sem_new(void) {
    aos_sem_t* sem = malloc(sizeof(aos_sem_t)); 
    if (!sem) {
        return NULL;
    }
    aos_sem_new(sem, 0);
    return sem;
}

static void hal_sem_del(void *sem) {
    aos_sem_t* sem_ptr = (aos_sem_t*)sem;
    if (!sem_ptr) {
        return;
    }
    aos_sem_free(sem_ptr);
    free(sem_ptr);
}

static bool hal_sem_wait(void* sem, uint32_t wait_tick) {
    aos_sem_t* sem_ptr = (aos_sem_t*)sem;
    if (!sem_ptr) {
        return false;
    }
    return 0 == aos_sem_wait(sem_ptr, wait_tick);
}

static void hal_sem_post(void* sem) {
    aos_sem_t* sem_ptr = (aos_sem_t*)sem;
    if (!sem_ptr) {
        return;
    }
    aos_sem_signal(sem_ptr);
}

static void* hal_mutex_new(void)
{
    aos_mutex_t* mutex = malloc(sizeof(aos_mutex_t));
    if (!mutex) {
        return NULL;
    }
    aos_mutex_new(mutex);
    return mutex;
}

static void hal_mutex_del(void* mutex)
{
    aos_mutex_t* mutex_ptr = (aos_mutex_t*)mutex;
    if (!mutex_ptr) {
        return;
    }
    aos_mutex_free(mutex_ptr);
    free(mutex_ptr);
}

static void hal_mutex_lock(void* mutex)
{
    aos_mutex_t* mutex_ptr = (aos_mutex_t*)mutex;
    if (!mutex_ptr) {
        return;
    }
    aos_mutex_lock(mutex_ptr, AOS_WAIT_FOREVER);
}

static void hal_mutex_unlock(void* mutex)
{
    aos_mutex_t* mutex_ptr = (aos_mutex_t*)mutex;
    if (!mutex_ptr) {
        return;
    }
    aos_mutex_unlock(mutex_ptr);
}

const protocol_hal_t hal_aos = {
    .dev = NULL,
    .send = uart_send,
    
    .sem_new = hal_sem_new,
    .sem_del = hal_sem_del,
    .sem_wait = hal_sem_wait,
    .sem_post = hal_sem_post,

    .mutex_new = hal_mutex_new,
    .mutex_del = hal_mutex_del,
    .mutex_lock = hal_mutex_lock,
    .mutex_unlock = hal_mutex_unlock
};
